﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using Wedn.Net.Utility;

namespace Wedn.Net.UI.Handlers
{
    /// <summary>
    /// 资源加载处理程序
    /// </summary>
    public abstract class LoadHandler : BaseHandler
    {
        /// <summary>
        /// 资源加载处理程序构造函数
        /// </summary>
        protected LoadHandler()
        {
            //防盗链
        }

        /// <summary>
        /// 处理请求方法
        /// </summary>
        /// <param name="context">HTTP上下文</param>
        public abstract override void ProcessRequest(HttpContext context);

        /// <summary>
        /// 执行加载
        /// </summary>
        /// <param name="context"></param>
        public void Load(HttpContext context)
        {
            if (context.Request.Headers["If-Modified-Since"] != null && TimeSpan.FromTicks(DateTime.Now.Ticks - DateTime.Parse(context.Request.Headers["If-Modified-Since"]).Ticks).Days < 30)
            {
                //测试代码,在这里会发现,当浏览器返回304状态时,下面的日期并不会输出 
                context.Response.StatusCode = 304;
                context.Response.Headers.Add("Content-Encoding", "gzip");
                context.Response.StatusDescription = "Not Modified";
            }
            else
            {
                LoadResource(context);
                //设置客户端缓存状态 
                SetClientCaching(context, DateTime.Now);
            }

        }

        /// <summary>
        /// 加载资源文件
        /// </summary>
        /// <param name="context">Http请求上下文</param>
        public void LoadResource(HttpContext context)
        {
            string query = context.Request.QueryString.ToString();
            object cacheObj = CacheHelper.GetCache(query);
            string res = cacheObj == null ? string.Empty : cacheObj.ToString();
            string ext = context.Response.ContentType != "text/css" ? "js" : "css";
            if (string.IsNullOrEmpty(res))
            {
                string load = RequestHelper.QueryString("load");
                string dir = RequestHelper.QueryString("dir");
                if (string.IsNullOrEmpty(dir))
                    dir = ext == "js" ? "scripts" : "styles";
                else
                    dir = dir.Replace('.', '/');
                string[] files = load.Split(',');
                var sbd = new StringBuilder();
                foreach (var path in files.Select(item => context.Server.MapPath(string.Format("/Content/{0}/{1}.{2}", dir, item.Replace('.', '/'), ext))).Where(File.Exists))
                {
                    sbd.AppendLine(File.ReadAllText(path));
                }
                if (sbd.Length == 0)
                    return;
                //res = Regex.Replace(sbd.ToString(), @"[\t\r\n]|(\s{2,})", string.Empty, RegexOptions.Multiline);
                res = sbd.ToString();
                CacheHelper.SetCache(context.Request.QueryString.ToString(), res);
            }
            context.Response.Write(ext != "css" ? res : res.Replace("../", "../content/"));
        }

        /// <summary>
        /// 设置客户端缓存
        /// </summary>
        /// <param name="context">Http请求上下文</param>
        /// <param name="lastModified">最后修改时间</param>
        public void SetClientCaching(HttpContext context, DateTime lastModified)
        {
            context.Response.Cache.SetETag(lastModified.Ticks.ToString());
            context.Response.Cache.SetLastModified(lastModified);
            //public 以指定响应能由客户端和共享（代理）缓存进行缓存。 
            context.Response.Cache.SetCacheability(HttpCacheability.Public);
            //是允许文档在被视为陈旧之前存在的最长绝对时间。 
            context.Response.Cache.SetMaxAge(new TimeSpan(30, 0, 0, 0));
            //将缓存过期从绝对时间设置为可调时间 
            context.Response.Cache.SetSlidingExpiration(true);
        }
    }
}
